/*
 * date: 2009-11-20 
 * author: Maciej Smolenski <jezdnia@gmail.com>
 */
#ifndef _RPC_CONFIG_DATA_HPP_
#define _RPC_CONFIG_DATA_HPP_

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/set.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/offset_ptr.hpp>

#include <string>
#include <set>

#include "rpc_common_data.hpp"

namespace rpc_config
{

template <typename AT>
struct rpc_host_entry{
	AT address;
	long port;
	protocol_t protocol;	

	rpc_host_entry(const AT p_address, const long p_port, const protocol_t p_protocol);			
	rpc_host_entry(const rpc_host_entry<AT> &he);
	bool operator<(const rpc_host_entry<AT> &he) const;
};

template <typename AT>
rpc_host_entry<AT>::rpc_host_entry(const AT p_address, const long p_port, const protocol_t p_protocol) : address(p_address), port(p_port), protocol(p_protocol) {};					

template <typename AT>
rpc_host_entry<AT>::rpc_host_entry(const rpc_host_entry<AT> &he) : address(he.address), port(he.port), protocol(he.protocol) {};

template <typename AT>
bool rpc_host_entry<AT>::operator<(const rpc_host_entry<AT> &he) const{
	if (address.compare(he.address)<0) return true;
	else if (port<he.port) return true;
	else if (protocol<he.protocol) return true;
	else return false;
};

struct rpc_host_entry_string;
struct rpc_host_entry_shm_string;

struct rpc_host_entry_string : public rpc_host_entry<std::string>
{
	rpc_host_entry_string(const std::string p_address, const long p_port, const protocol_t p_protocol);
	rpc_host_entry_string(const rpc_host_entry_shm_string &hes);
};

struct rpc_host_entry_shm_string : public rpc_host_entry<shm_string>
{
	rpc_host_entry_shm_string(const shm_string p_address, const long p_port, const protocol_t p_protocol);
	rpc_host_entry_shm_string(const rpc_host_entry_string &hes, shm_char_allocator &al);	
};



typedef std::set<rpc_host_entry_string> stdset;
typedef bi::managed_shared_memory::allocator<rpc_host_entry_shm_string>::type shm_rpc_host_entry_shm_string_allocator;
typedef bi::set<rpc_host_entry_shm_string, std::less<rpc_host_entry_shm_string>, shm_rpc_host_entry_shm_string_allocator> biset;

result_t std_set_to_bi_set(bi::managed_shared_memory &segment, const stdset &si, biset &so);
result_t bi_set_to_std_set(bi::managed_shared_memory &segment, const biset &si, stdset &so);

struct rpcm_config{
	long m_delay;
	long m_ping_timeout;
	long m_portmap_timeout;
	int m_pgroup;
	bi::offset_ptr<biset> m_hosts;	
	result_t init(bi::managed_shared_memory &m_segment);
	result_t deinit(bi::managed_shared_memory &m_segment);
};

std::ostream &operator<<(std::ostream &os, const rpc_host_entry_string &r);

}

#endif
